package org.tea.inventory.admin.config;

import lombok.extern.slf4j.Slf4j;
import org.tea.inventory.base.exception.ApplicationException;
import org.tea.inventory.base.util.ResponseUtil;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 统一异常处理器
 *
 * @author gourd.hu
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {


    //	/**
//	 * 处理自定义业务异常
//	 * @param ex
//	 * @return
//	 */
//	@ResponseStatus(HttpStatus.OK)
//	@ExceptionHandler(value = BusinessException.class)
//	public ErrorResponse handleException(BusinessException ex) {
//		printApiCodeException(ex.getResponseEnum(), ex);
//		return ErrorResponse.result(ex.getResponseEnum().getCode(),ex.getResponseEnum().getMessage());
//	}
//
//	/**
//	 * 处理权限异常
//	 * @param ex
//	 * @return
//	 */
//	@ResponseStatus(HttpStatus.OK)
//	@ExceptionHandler(value = PreAuthorizeException.class)
//	public ErrorResponse handleException(PreAuthorizeException ex) {
//		printApiCodeException(ex.getResponseEnum(), ex);
//		return ErrorResponse.result(ex.getResponseEnum().getCode(),ex.getResponseEnum().getMessage());
//	}
//
//	/**
//	 * 非法参数验证异常
//	 *
//	 * @param ex
//	 * @return
//	 */
//	@ResponseStatus(HttpStatus.OK)
//	@ExceptionHandler({MethodArgumentNotValidException.class})
//	public ErrorResponse handleException(MethodArgumentNotValidException ex) {
//		printApiCodeException(ResponseEnum.BAD_REQUEST, ex);
//		BindingResult bindingResult = ex.getBindingResult();
//		List<String> list = new ArrayList<>();
//		List<FieldError> fieldErrors = bindingResult.getFieldErrors();
//		for (FieldError fieldError : fieldErrors) {
//			list.add(fieldError.getDefaultMessage());
//		}
//		return ErrorResponse.result(ResponseEnum.BAD_REQUEST,list);
//	}
//
//	/**
//	 * 非法参数验证异常
//	 *
//	 * @param ex
//	 * @return
//	 */
//	@ResponseStatus(HttpStatus.OK)
//	@ExceptionHandler({BindException.class})
//	public ErrorResponse handleException(BindException ex) {
//		BindingResult bindingResult = ex.getBindingResult();
//		List<String> list = new ArrayList<>();
//		List<FieldError> fieldErrors = bindingResult.getFieldErrors();
//		for (FieldError fieldError : fieldErrors) {
//			list.add(fieldError.getDefaultMessage());
//		}
//		return ErrorResponse.result(ResponseEnum.BAD_REQUEST,list);
//	}
//
//	/**
//	 * 缺少请求参数异常处理
//	 *
//	 * @param ex
//	 * @return
//	 */
//	@ExceptionHandler(value = MissingServletRequestParameterException.class)
//	@ResponseStatus(HttpStatus.OK)
//	public ErrorResponse handleException(MissingServletRequestParameterException ex) {
//		printApiCodeException(ResponseEnum.BAD_REQUEST, ex);
//		return ErrorResponse.result(ResponseEnum.BAD_REQUEST);
//	}
//
//	/**
//	 * 404异常处理
//	 * @param ex
//	 * @return
//	 */
//	@ResponseStatus(HttpStatus.OK)
//	@ExceptionHandler(NoHandlerFoundException.class)
//	public ErrorResponse handleException(NoHandlerFoundException ex) {
//		printApiCodeException(ResponseEnum.NOT_FOUND, ex);
//		return ErrorResponse.result(ResponseEnum.NOT_FOUND);
//	}
//
//	/**
//	 * 不支持方法异常处理
//	 *
//	 * @param ex
//	 * @return
//	 */
//	@ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
//	@ResponseStatus(HttpStatus.OK)
//	public ErrorResponse handleException(HttpRequestMethodNotSupportedException ex) {
//		printApiCodeException(ResponseEnum.METHOD_NOT_ALLOWED, ex);
//		return ErrorResponse.result(ResponseEnum.METHOD_NOT_ALLOWED);
//	}
//
//	/**
//	 * 非法获取异常
//	 *
//	 * @param ex
//	 * @return
//	 */
//	@ExceptionHandler(value = IllegalAccessException.class)
//	@ResponseStatus(HttpStatus.OK)
//	public ErrorResponse handleException(IllegalAccessException ex) {
//		printApiCodeException(ResponseEnum.ILLEGAL_ACCESS, ex);
//		return ErrorResponse.result(ResponseEnum.ILLEGAL_ACCESS);
//	}
//
//	/**
//	 * spring默认上传大小100MB 超出大小捕获异常MaxUploadSizeExceededException
//	 */
//	@ExceptionHandler(MaxUploadSizeExceededException.class)
//	public ErrorResponse handleException(MaxUploadSizeExceededException ex) {
//		printApiCodeException(ResponseEnum.FILE_TOO_LARGE, ex);
//		return ErrorResponse.result(ResponseEnum.FILE_TOO_LARGE);
//	}
//
//
//
//	/**
//	 * 默认的异常处理
//	 *
//	 * @param ex
//	 * @return
//	 */
//	@ExceptionHandler(value = Exception.class)
//	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
//	public ErrorResponse handleException(Exception ex) {
//		printApiCodeException(ResponseEnum.INTERNAL_SERVER_ERROR, ex);
//		return ErrorResponse.result(ResponseEnum.INTERNAL_SERVER_ERROR.getCode(),ex.getCause().getMessage());
//	}
//
//	/**
//	 * 获取httpStatus格式化字符串
//	 *
//	 * @param responseEnum
//	 * @return
//	 */
//	private String getApiCodeString(IResponseEnum responseEnum) {
//		if (responseEnum != null) {
//			return String.format("errorCode: %s, errorMessage: %s", responseEnum.getCode(), responseEnum.getMessage());
//		}
//		return null;
//	}
//
//	/**
//	 * 打印错误码及异常
//	 *
//	 * @param responseEnum
//	 * @param exception
//	 */
//	private void printApiCodeException(IResponseEnum responseEnum, Exception exception) {
//		log.error(getApiCodeString(responseEnum), exception);
//	}
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(Exception.class)
    public Object exceptionHandler(Exception e) {
        e.printStackTrace();
        return ResponseUtil.serious();
    }

    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(MethodArgumentTypeMismatchException.class)
    public Object argumentHandler(MethodArgumentTypeMismatchException e) {
        e.printStackTrace();
        return ResponseUtil.badArgumentValue();
    }
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler({MethodArgumentNotValidException.class})
    public Object handleException(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        StringBuilder message = new StringBuilder();
        if (bindingResult.hasErrors()) {
            List<ObjectError> allErrors = bindingResult.getAllErrors();
            for (ObjectError allError : allErrors) {
                message.append(allError.getDefaultMessage()).append(", ");
            }
        }
        return ResponseUtil.fail(400,message.toString());
    }
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(ApplicationException.class)
    public Object repeatCommittHandler(ApplicationException e) {
        e.printStackTrace();
        return ResponseUtil.fail(e.getErrno(),e.getMessage());
    }
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(IllegalArgumentException.class)
    public Object illegalArgumentExceptionHandler(IllegalArgumentException e) {
        e.printStackTrace();
        return ResponseUtil.fail(402,e.getMessage());
    }

    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler({BindException.class})
    public Object handleException(BindException ex) {
        BindingResult bindingResult = ex.getBindingResult();
        StringBuilder message = new StringBuilder();
        if (bindingResult.hasErrors()) {
            List<ObjectError> allErrors = bindingResult.getAllErrors();
            String error = allErrors.stream().map(ObjectError::getDefaultMessage).collect(Collectors.joining(","));
            message.append(error);
        }
        return ResponseUtil.fail(400,message.toString());
    }


}
